#include "TestSample.h"
#include "imgui.h"
#include "GLFW/glfw3.h"
#include "glad/glad.h"
#include "glm/gtx/transform.hpp"
TestSample::TestSample() {
	GLShader vertShader =  GLShader("../Assets/Shaders/test.vert");
	GLShader fragShader =  GLShader("../Assets/Shaders/test.frag");
	program = new GLProgram(vertShader,fragShader);
	kBufferSize = sizeof(FrameData);
}

TestSample::~TestSample() {
	delete program;
	glDeleteBuffers(1, &perFrameDataBuffer);
	glDeleteVertexArrays(1, &vao);
}

void TestSample::Init() {
	color = glm::vec4(1.0f,0.0f,0.0f,1.0f);
	// mesh
	glCreateVertexArrays(1, &vao);
	glBindVertexArray(vao);

	glCreateBuffers(1, &perFrameDataBuffer);
	glNamedBufferStorage(perFrameDataBuffer, kBufferSize, nullptr, GL_DYNAMIC_STORAGE_BIT);
	glBindBufferRange(GL_UNIFORM_BUFFER, 0, perFrameDataBuffer, 0, kBufferSize);

	
	glCreateBuffers(1, &meshData);

	const aiScene* scene = aiImportFile("../Assets/Meshs/rubber_duck/scene.gltf", aiProcess_Triangulate);
	if (!scene || !scene->HasMeshes())
	{
		printf("Unable to load ../Assets/Meshs/rubber_duck/scene.gltf\n");
		assert(false);
	}

	const aiMesh* mesh = scene->mMeshes[0];
	std::vector<vec3> positions;
	for (unsigned int i = 0; i != mesh->mNumFaces; i++)
	{
		const aiFace& face = mesh->mFaces[i];
		const unsigned int idx[3] = { face.mIndices[0], face.mIndices[1], face.mIndices[2] };
		for (int j = 0; j != 3; j++)
		{
			const aiVector3D v = mesh->mVertices[idx[j]];
			positions.push_back(vec3(v.x, v.z, v.y));
		}
	}

	aiReleaseImport(scene);

	glNamedBufferStorage(meshData, sizeof(vec3) * positions.size(), positions.data(), 0);
	glVertexArrayVertexBuffer(vao, 0, meshData, 0, sizeof(vec3));
	glEnableVertexArrayAttrib(vao, 0);
	glVertexArrayAttribFormat(vao, 0, 3, GL_FLOAT, GL_FALSE, 0);
	glVertexArrayAttribBinding(vao, 0, 0);
	numVertices = static_cast<int>(positions.size());

	glEnable(GL_DEPTH_TEST);
	glEnable(GL_POLYGON_OFFSET_LINE);
	glPolygonOffset(-1.0f, -1.0f);
}

void TestSample::Update(float deltatime) {
	angle += deltatime * 10.0f;
	if (angle >= 360.0f) {
		angle = 0.0f;
	}
}

void TestSample::Render(float aspect) {
	m = glm::rotate(glm::translate(mat4(1.0f), vec3(0.0f)), glm::radians(angle), vec3(0.0f, 1.0f, 0.0f));
	p = glm::perspective(45.0f, aspect, 0.1f, 1000.0f);
	v = glm::lookAt(glm::vec3(0.0f,1.5f,2.5f),glm::vec3(0.0f),glm::vec3(0.0f,1.0f,0.0f));
	FrameData = { p * v * m,false };

	program->useProgram();
	glNamedBufferSubData(perFrameDataBuffer, 0, kBufferSize, &FrameData);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	glDrawArrays(GL_TRIANGLES, 0, numVertices);

	FrameData.isWireframe = true;
	glNamedBufferSubData(perFrameDataBuffer, 0, kBufferSize, &FrameData);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glDrawArrays(GL_TRIANGLES, 0, numVertices);
	
}

void TestSample::OnGUI() {
	ImGui::Text("Test");
}

void TestSample::ShutDown() {
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_POLYGON_OFFSET_LINE);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
